import { renderComponent } from "../react-dom";

const setStateQueue = [];
// 保存当前的组件
const renderQueue = [];
/**
 * 
 * 1.异步更新state,短时间内吧setState合并到一个队列中（先进先出）
 * 2，一段时间后，循环清空，渲染组件
 * @param {*} stateChange 
 * @param {*} component 
 */
export function enqueue(stateChange, component) {

    // 如果setStateQueue的长度是0,也就是在上次flush执行之后第一次往队列里添加
    if (setStateQueue.length === 0) {
        defer(flush);
    }

    // 短时间内存储到队列中
    setStateQueue.push({ stateChange, component })
    // 如果renderQueue为空时候，将组建添加到队列中
    let r = renderQueue.some(item => item === component);
    // 第一次添加组件
    if (!r) {
        renderQueue.push(component);
    }
}

// 一段时间后
function flush() {
    let item, component;
    // 遍历state
    while (item = setStateQueue.shift()) {
        const { stateChange, component } = item;
        // 如果没有prevState,则将当前的state作为初始的prevState
        if (!component.prevState) {
            component.prevState = Object.assign({}, component.state);
        }
        // 如果stateChange是一个方法,也就是setState的第一种形式
        if (typeof stateChange === 'function') {
            Object.assign(component.state, stateChange(component.prevState, component.props))
        } else {
            // 如果stateChange是一个对象,则直接合并到setState中
            Object.assign(component.state, stateChange);
        }
        component.prevState = component.state;
    }
    // 遍历组件，进行渲染队列最后进来的组件
    while (component = renderQueue.shift()) {
        renderComponent(component);
    }
}

function defer(fn) {
    return Promise.resolve().then(fn);
}